﻿Imports System.Activities
Imports System.Activities.Statements
Imports System.ComponentModel
Imports System.Windows.Markup
Imports System.Activities.Validation
Imports System.Activities.Presentation.Metadata
Imports System.Activities.Core.Presentation
Imports System.Drawing

<ContentProperty("BODY")>
Public Class CommentOutActivity
    Inherits CodeActivity
    Implements IRegisterMetadata

    <Browsable(False)>
    Public Property Body As Activity

    Public Sub New()
        Me.DisplayName = GetResourceStrings("ActCODisplayName", "コメントアウト")
        Me.Body = New Sequence
        Me.Constraints.Add(ValidateChildActivityIsNothing)
        Me.Constraints.Add(ValidateBodyIsSequence)
    End Sub

    Public Shared Function ValidateChildActivityIsNothing() As Constraint
        Dim element As New DelegateInArgument(Of CommentOutActivity)

        Dim funclambda As System.Linq.Expressions.Expression(Of Func(Of ActivityContext, Boolean)) =
            Function(env) ((element.Get(env).Body IsNot Nothing) AndAlso _
                                 (TypeOf element.Get(env).Body Is Sequence) AndAlso _
                                 (DirectCast(element.Get(env).Body, Sequence).Activities.Count > 0))

        Return New Constraint(Of CommentOutActivity) With {
            .Body = New ActivityAction(Of CommentOutActivity, ValidationContext) With {
                .Argument1 = element,
                .Handler = New AssertValidation With {
                    .IsWarning = True,
                    .Assertion = New InArgument(Of Boolean)(funclambda),
                    .Message = New InArgument(Of String)(GetResourceStrings("ActCONoNeed", "必要がない場合はアクティビティを削除してください").ToString)
                }
            }
        }
    End Function

    Public Shared Function ValidateBodyIsSequence() As Constraint
        Dim element As New DelegateInArgument(Of CommentOutActivity)

        Dim funclambda As System.Linq.Expressions.Expression(Of Func(Of ActivityContext, Boolean)) =
            Function(env) ((element.Get(env).Body IsNot Nothing) AndAlso _
                                 (TypeOf element.Get(env).Body Is Sequence))

        Return New Constraint(Of CommentOutActivity) With {
            .Body = New ActivityAction(Of CommentOutActivity, ValidationContext) With {
                .Argument1 = element,
                .Handler = New AssertValidation With {
                    .IsWarning = True,
                    .Assertion = New InArgument(Of Boolean)(funclambda),
                    .Message = New InArgument(Of String)(GetResourceStrings("ActCONeedSequence", "Sequence アクティビティを必ず設置してください").ToString)
                }
            }
        }

    End Function

    Protected Overrides Sub Execute(ByVal context As System.Activities.CodeActivityContext)
        'No Execute
    End Sub

#Region "メタデータ"

    Public Sub Register() Implements System.Activities.Presentation.Metadata.IRegisterMetadata.Register
        Dim metadata As New DesignerMetadata
        metadata.Register()

        Dim builder As New AttributeTableBuilder
        builder.AddCustomAttributes(GetType(CommentOutActivity),
                            New DesignerAttribute(GetType(CommentOutActivityDesigner)),
                            New ToolboxBitmapAttribute("Images/Activity/commentout.png")
                            )

        MetadataStore.AddAttributeTable(builder.CreateTable)
    End Sub

#End Region

#Region "その他"

    ''' <summary>リソースより文字列の取得</summary>
    Private Shared Function GetResourceStrings(ByVal resourceName As String, ByVal defaultStrings As String)
        Dim locMes = CStr(Application.Current.TryFindResource(resourceName))
        If (locMes Is Nothing) OrElse (locMes.Trim = "") Then locMes = defaultStrings
        Return locMes
    End Function

#End Region

End Class
